package controllers

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"

	"dcarpai-guider/internal/models"
	"dcarpai-guider/internal/services"
)

// ToolController 工具控制器
type ToolController struct {
	toolService *services.ToolService
	logger      *zap.Logger
}

// NewToolController 创建新的工具控制器
func NewToolController(toolService *services.ToolService, logger *zap.Logger) *ToolController {
	return &ToolController{
		toolService: toolService,
		logger:      logger,
	}
}

// GetAllTools 获取所有工具
// @Summary 获取所有工具
// @Description 获取系统中所有工具的列表
// @Tags 工具
// @Produce json
// @Security BearerAuth
// @Success 200 {array} models.Tool
// @Failure 401 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /tools [get]
func (tc *ToolController) GetAllTools(c *gin.Context) {
	tools, err := tc.toolService.GetAllTools()
	if err != nil {
		tc.logger.Error("获取工具列表失败", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取工具列表失败",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取工具列表成功",
		"data":    tools,
	})
}

// GetTool 根据ID获取工具
// @Summary 获取工具详情
// @Description 根据工具ID获取工具的详细信息
// @Tags 工具
// @Produce json
// @Security BearerAuth
// @Param id path int true "工具ID"
// @Success 200 {object} models.Tool
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /tools/{id} [get]
func (tc *ToolController) GetTool(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的工具ID",
		})
		return
	}

	tool, err := tc.toolService.GetTool(id)
	if err != nil {
		tc.logger.Warn("获取工具失败", zap.Int("id", id), zap.Error(err))
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取工具成功",
		"data":    tool,
	})
}

// CreateTool 创建新工具
// @Summary 创建工具
// @Description 创建一个新的工具
// @Tags 工具
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param tool body models.ToolRequest true "工具信息"
// @Success 201 {object} models.Tool
// @Failure 400 {object} map[string]interface{}
// @Failure 500 {object} map[string]interface{}
// @Router /tools [post]
func (tc *ToolController) CreateTool(c *gin.Context) {
	var req models.ToolRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		tc.logger.Warn("创建工具请求参数错误", zap.Error(err))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	// 基本验证
	if req.Name == "" || req.EmbedURL == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "工具名称和嵌入URL不能为空",
		})
		return
	}

	tool, err := tc.toolService.CreateTool(&req)
	if err != nil {
		tc.logger.Error("创建工具失败",
			zap.String("name", req.Name),
			zap.Error(err),
		)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "创建工具失败",
			"error":   err.Error(),
		})
		return
	}

	tc.logger.Info("创建工具成功",
		zap.String("name", tool.Name),
		zap.Int("id", tool.ID),
	)

	c.JSON(http.StatusCreated, gin.H{
		"code":    201,
		"message": "创建工具成功",
		"data":    tool,
	})
}

// UpdateTool 更新工具
// @Summary 更新工具
// @Description 更新指定ID的工具信息
// @Tags 工具
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "工具ID"
// @Param tool body models.ToolRequest true "工具信息"
// @Success 200 {object} models.Tool
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /tools/{id} [put]
func (tc *ToolController) UpdateTool(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的工具ID",
		})
		return
	}

	var req models.ToolRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		tc.logger.Warn("更新工具请求参数错误", zap.Error(err))
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	// 基本验证
	if req.Name == "" || req.EmbedURL == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "工具名称和嵌入URL不能为空",
		})
		return
	}

	tool, err := tc.toolService.UpdateTool(id, &req)
	if err != nil {
		tc.logger.Error("更新工具失败",
			zap.Int("id", id),
			zap.String("name", req.Name),
			zap.Error(err),
		)
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": err.Error(),
		})
		return
	}

	tc.logger.Info("更新工具成功",
		zap.String("name", tool.Name),
		zap.Int("id", id),
	)

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "更新工具成功",
		"data":    tool,
	})
}

// DeleteTool 删除工具
// @Summary 删除工具
// @Description 删除指定ID的工具
// @Tags 工具
// @Produce json
// @Security BearerAuth
// @Param id path int true "工具ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /tools/{id} [delete]
func (tc *ToolController) DeleteTool(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的工具ID",
		})
		return
	}

	if err := tc.toolService.DeleteTool(id); err != nil {
		tc.logger.Error("删除工具失败", zap.Int("id", id), zap.Error(err))
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": err.Error(),
		})
		return
	}

	tc.logger.Info("删除工具成功", zap.Int("id", id))

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "删除工具成功",
	})
}

// GetToolStatus 获取工具状态
// @Summary 获取工具状态
// @Description 获取工具的运行状态，包括Consul健康检查
// @Tags 工具
// @Produce json
// @Security BearerAuth
// @Param id path int true "工具ID"
// @Success 200 {object} map[string]interface{}
// @Failure 400 {object} map[string]interface{}
// @Failure 404 {object} map[string]interface{}
// @Router /tools/{id}/status [get]
func (tc *ToolController) GetToolStatus(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "无效的工具ID",
		})
		return
	}

	status, err := tc.toolService.GetToolStatus(id)
	if err != nil {
		tc.logger.Error("获取工具状态失败", zap.Int("id", id), zap.Error(err))
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取工具状态成功",
		"data":    status,
	})
}

// GetActiveTools 获取活跃的工具
// @Summary 获取活跃工具
// @Description 获取状态为活跃的工具列表
// @Tags 工具
// @Produce json
// @Security BearerAuth
// @Success 200 {array} models.Tool
// @Failure 500 {object} map[string]interface{}
// @Router /tools/active [get]
func (tc *ToolController) GetActiveTools(c *gin.Context) {
	tools, err := tc.toolService.GetActiveTools()
	if err != nil {
		tc.logger.Error("获取活跃工具列表失败", zap.Error(err))
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "获取活跃工具列表失败",
			"error":   err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "获取活跃工具列表成功",
		"data":    tools,
	})
}
